/**
 * 
 */
package com.dalonedrow.engine.sprite.base;

import com.dalonedrow.engine.ui.base.SimpleInsets;

/**
 * @author Donald
 */
public abstract class SpriteBaseImpl implements SpriteBase {
	/** the unmodified value of the alpha color channel. */
	private float			alpha			= 1;
	/** the unmodified value of the blue color channel. */
	private float			blue			= 1;
	/** flag for displaying debuging output. */
	private boolean			debug			= false;
	/** all flags assigned. */
	private long			flags;
	/** the number of values in the storage array for rendering values. */
	private int				floatStoreNum	= 0;
	/** the full value of the alpha color channel, including modifications. */
	private float			fullAlpha;
	/** the full value of the blue color channel, including modifications. */
	private float			fullBlue;
	/** the full value of the green color channel, including modifications. */
	private float			fullGreen;
	/** the full value of the red color channel, including modifications. */
	private float			fullRed;
	/** the unmodified value of the green color channel. */
	private float			green			= 1;
	/** the value of all modifications applied to the alpha color channel. */
	private float			modAlpha;
	/** the value of all modifications applied to the blue color channel. */
	private float			modBlue;
	/** the value of all modifications applied to the green color channel. */
	private float			modGreen;
	/** the value of all modifications applied to the red color channel. */
	private float			modRed;
	/** the time the sprite's move started. */
	private long			moveStart;
	/**
	 * the length of time the sprite's move lasts. At the end of the time, the
	 * sprite is moved based on its direction and velocity.
	 */
	private long			moveTimer;
	/** the parent container. */
	private int				parentRefId		= -1;
	/** the sprite's partial offsets. */
	private SimpleInsets	partialInsets	= new SimpleInsets(0, 0, 0, 0);
	/**
	 * private Insets partialInsets = new Insets(0, 0, 0, 0); /** the unmodified
	 * value of the red color channel.
	 */
	private float			red				= 1;
	/** the scale factor applied to the height. */
	private float			scaleFactorHeight;
	/** the scale factor applied to the width. */
	private float			scaleFactorWidth;
	/** the velocity. */
	private SimpleVector3	velocity;
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void assignFlag(final long flag) {
		flags |= flag;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void clearFlags() {
		flags = 0;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void clearFloatStore() {
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getAlpha() {
		return alpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getBlue() {
		return blue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int getFloatStoreNumber() {
		return floatStoreNum;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullAlpha() {
		return fullAlpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullBlue() {
		return fullBlue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullGreen() {
		return fullGreen;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getFullRed() {
		return fullRed;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getGreen() {
		return green;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModAlpha() {
		return modAlpha;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModBlue() {
		return modBlue;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModGreen() {
		return modGreen;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getModRed() {
		return modRed;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final long getMoveDuration() {
		return moveTimer;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final long getMoveStart() {
		return moveStart;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int getParentRefId() {
		return parentRefId;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final SimpleInsets getPartialOffsets() {
		return partialInsets;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getRed() {
		return red;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getScaleFactorHeight() {
		return scaleFactorHeight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final float getScaleFactorWidth() {
		return scaleFactorWidth;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final SimpleVector3 getVelocity() {
		return velocity;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final boolean hasFlag(final long flag) {
		return (flags & flag) == flag;
	}
	/**
	 * Gets the debugging output flag.
	 * @return <code>boolean</code>
	 */
	@Override
	public final boolean isDebug() {
		return debug;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeFlag(final long flag) {
		flags &= ~flag;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setAlpha(final float a) {
		alpha = a;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setBlue(final float b) {
		blue = b;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setColor(final float[] color) throws Exception {
		final int three = 3, four = 4;
		if (color.length < three
				|| color.length > four) {
			throw new Exception("Invalid color array.");
		}
		red = color[0];
		green = color[1];
		blue = color[2];
		if (color.length == four) {
			alpha = color[three];
		}
		floatStoreNum = 0;
	}
	/**
	 * Sets the debugging output flag.
	 * @param val the flag to set
	 */
	@Override
	public final void setDebug(final boolean val) {
		debug = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFloatStoreNumber(final int val) {
		floatStoreNum = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullAlpha(final float a) {
		fullAlpha = a;
		if (fullAlpha > 1f) {
			fullAlpha = 1f;
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullBlue(final float b) {
		fullBlue = b;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullGreen(final float g) {
		fullGreen = g;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setFullRed(final float r) {
		fullRed = r;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setGreen(final float g) {
		green = g;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModAlpha(final float a) {
		modAlpha = a;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModBlue(final float b) {
		modBlue = b;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModGreen(final float g) {
		modGreen = g;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setModRed(final float r) {
		modRed = r;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setMoveStart(final long time) {
		moveStart = time;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setMoveTimer(final long time) {
		moveTimer = time;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setParentRefId(final int val) {
		parentRefId = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setRed(final float r) {
		red = r;
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setScaleFactorHeight(final float val) {
		scaleFactorHeight = val;
		if (scaleFactorHeight < 0) {
			scaleFactorHeight = 0;
		}
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setScaleFactorWidth(final float val) {
		scaleFactorWidth = val;
		if (scaleFactorWidth < 0) {
			scaleFactorWidth = 0;
		}
		floatStoreNum = 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setVelocity(final double x, final double y) {
		if (velocity != null) {
			velocity.setX(x);
			velocity.setY(y);
		} else {
			velocity = new SimpleVector3(x, y, 1);
		}
		setFloatStoreNumber(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setVelocity(final double x, final double y, 
			final double z) {
		if (velocity != null) {
			velocity.set(x, y, z);
		} else {
			velocity = new SimpleVector3(x, y, z);
		}
		setFloatStoreNumber(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setVelocity(final SimpleVector3 v) {
		velocity = v;
		setFloatStoreNumber(0);
	}
}
